package com.blockchain.wmm.block.merkle;

import cn.hutool.crypto.digest.DigestUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wangzun
 * 实现一个MerkleTree结构
 * */
public class MerkleTree {
    private List<String> list;
    private String root;

    public MerkleTree(){}
    public MerkleTree(List<String> list) {
        this.list = list;
    }

    /**
     * 通过build()将一个List<String>构建为一个MerkleTree.算出hashRoot
     * */
    public MerkleTree build() {
        List<String> tempList = new ArrayList<>(this.list);
        List<String> newList = getNewList(tempList);

        //when newList.size() == 1 then you'll got the root hash
        while(newList.size() != 1) {
            newList = getNewList(newList);
        }
        this.root = newList.get(0);
        return this;
    }

    /**
     * 计算某一层节点的hash,直到size() == 1 则为hashRoot
     * */
    private List<String> getNewList(List<String> tempList) {
        List<String> newList = new ArrayList<>();
        int index = 0;
        while(index <  tempList.size()) {
            //get left node
            String left = tempList.get(index);
            index++;

            //get right node
            String right = "";
            if(index != tempList.size()) {
                right = tempList.get(index);
            }

            //sha to left&right node
            String sha2HexValue = DigestUtil.sha256Hex(left + right);
            //add sha2 to return list
            newList.add(sha2HexValue);
            index++;
        }
        return newList;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public String getRoot() {
        return root;
    }

    public void setRoot(String root) {
        this.root = root;
    }
}
